package com.cyy.common.service.impl;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.lang.Assert;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.cyy.common.constant.Constants;
import com.cyy.common.domain.BaseEntity;
import com.cyy.common.exception.ProcessException;
import com.cyy.common.mapper.CategoryMapper;
import com.cyy.common.pojo.dto.CategoryFormDto;
import com.cyy.common.pojo.dto.common.OptionDto;
import com.cyy.common.pojo.entity.Category;
import com.cyy.common.pojo.query.system.SystemCategoryQuery;
import com.cyy.common.pojo.vo.api.ApiCategoryVo;
import com.cyy.common.pojo.vo.system.SystemCategoryVo;
import com.cyy.common.service.CategoryService;
import com.cyy.common.utils.PageUtils;
import org.apache.commons.lang3.ObjectUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;

import java.util.Arrays;
import java.util.List;
import java.util.Objects;
import java.util.Optional;

/**
 * <p>
 * 分类表 服务实现类
 * </p>
 *
 * @author 曹云友
 * @since 2024-04-01
 */
@Service
public class CategoryServiceImpl extends ServiceImpl<CategoryMapper, Category> implements CategoryService {

    @Override
    public List<ApiCategoryVo> queryList() {
        return baseMapper.queryList();
    }

    @Override
    public List<OptionDto<String, Integer>> getOptions() {
        List<Category> categories = baseMapper.selectList(Wrappers.<Category>lambdaQuery()
                .select(Category::getId, Category::getName)
                .eq(Category::getStatus, Boolean.TRUE));
        if (CollectionUtil.isEmpty(categories)) {
            throw new ProcessException("未找到分类列表信息");
        }
        return categories.stream().map(item -> {
            OptionDto<String, Integer> dto = new OptionDto<>();
            dto.setValue(item.getId());
            dto.setLabel(item.getName());
            return dto;
        }).toList();
    }

    @Override
    public void addCategory(CategoryFormDto req) {
        // 参数判断 + 长度限制
        Assert.isFalse(StringUtils.isBlank(req.getName())
                ||
                req.getName().length() > 32);
        // 判断是否已存在
        boolean exists = baseMapper.exists(Wrappers.<Category>lambdaQuery()
                .eq(Category::getName, req.getName()));
        if (exists) {
            throw new ProcessException("已存在对应分类，请勿重复创建");
        }
        // 信息设置
        Category category = new Category();
        BeanUtils.copyProperties(req, category);
        category.setId(null);

        // 保存
        this.save(category);

    }

    @Override
    public void updateCategory(CategoryFormDto req) {
        // 参数校验
        Assert.isFalse(Objects.isNull(req.getId())
                ||
                (StringUtils.isBlank(req.getName()) && ObjectUtils.allNull(req.getSort(), req.getStatus())));
        // 参数修改
        Category category = new Category();
        BeanUtils.copyProperties(req, category);
        // 更新
        baseMapper.updateById(category);
    }

    @Override
    public void deleteCategories(String ids) {
        List<String> idList = Arrays.asList(ids.split(Constants.COMMA));

        if (CollectionUtil.isNotEmpty(idList)) {
            baseMapper.update(Wrappers.<Category>lambdaUpdate()
                    .set(BaseEntity::getStatus, Boolean.FALSE)
                    .in(BaseEntity::getId, idList)
            );
        }

    }

    @Override
    public IPage<SystemCategoryVo> getPage(SystemCategoryQuery query) {
        return baseMapper.getPage(PageUtils.getPage(), query);
    }

    @Override
    public CategoryFormDto getCategoryFormById(Integer id) {
        // 参数校验
        Assert.isFalse(id < 0);

        Category category = Optional.ofNullable(baseMapper.selectById(id))
                .orElseThrow(() -> new ProcessException("未找到对应信息"));

        CategoryFormDto res = new CategoryFormDto();
        BeanUtils.copyProperties(category, res);

        return res;
    }
}
